package com.seata.demo.account.controller;

import com.seata.demo.account.service.AccountService;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@RestController
public class AccountController {

    @Autowired
    private AccountService accountService;

    /**
     * 扣减账户余额（AT和XA模式）
     */
    @PostMapping("/account/debit")
    public void debit(@RequestParam("userId") String userId,
                     @RequestParam("money") BigDecimal money) {
        accountService.debit(userId, money);
    }
    
    /**
     * 恢复账户余额（Saga补偿）
     */
    @PostMapping("/account/revert")
    public void revert(@RequestParam("userId") String userId,
                     @RequestParam("money") BigDecimal money) {
        accountService.revert(userId, money);
    }

    /**
     * TCC模式 - 尝试扣减
     */
    @PostMapping("/account/tcc/tryDebit")
    public boolean tryDebit(@RequestParam("userId") String userId,
                           @RequestParam("money") BigDecimal money) {
        return accountService.tryDebit(userId, money);
    }

    /**
     * TCC模式 - 确认扣减
     */
    @PostMapping("/account/tcc/commit")
    public boolean commit(@RequestBody BusinessActionContext context) {
        String userId = context.getActionContext("userId").toString();
        BigDecimal money = new BigDecimal(context.getActionContext("money").toString());
        return accountService.confirmDebit(userId, money);
    }

    /**
     * TCC模式 - 取消扣减
     */
    @PostMapping("/account/tcc/rollback")
    public boolean rollback(@RequestBody BusinessActionContext context) {
        String userId = context.getActionContext("userId").toString();
        BigDecimal money = new BigDecimal(context.getActionContext("money").toString());
        return accountService.cancelDebit(userId, money);
    }
}
